/**
 * 项目名：化工企业安全生产信息化管理平台
 * 日期：    2020-03-01 22:19:08
 * Copyright (c) 2015- -版权所有
 */

package com.joysuch.wwyt.edu.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.zlg.common.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Maps;
import com.google.common.io.ByteStreams;
import com.joysuch.wwyt.bp.entity.BpDepart;
import com.joysuch.wwyt.bp.entity.BpJob;
import com.joysuch.wwyt.bp.repository.BpDepartDao;
import com.joysuch.wwyt.bp.repository.BpJobDao;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.common.util.PageDataUtils;
import com.joysuch.wwyt.core.common.util.PageDataUtils.PageDataConvert;
import com.joysuch.wwyt.core.entity.BaseImageRepository;
import com.joysuch.wwyt.core.entity.BaseUser;
import com.joysuch.wwyt.core.exception.BusinessRestrictionsException;
import com.joysuch.wwyt.core.mapper.BaseUserMapper;
import com.joysuch.wwyt.core.service.BaseImageRepositoryService;
import com.joysuch.wwyt.core.service.BaseUserService;
import com.joysuch.wwyt.core.service.BizCodeGeneratorFacade;
import com.joysuch.wwyt.edu.bean.*;
import com.joysuch.wwyt.edu.bean.EduExamRecordListBean.SearchEduExamRecord;
import com.joysuch.wwyt.edu.entity.*;
import com.joysuch.wwyt.edu.entity.dsl.QEduExamRecord;
import com.joysuch.wwyt.edu.enums.DistributionQuestionTypes;
import com.joysuch.wwyt.edu.enums.CharacterEntityEnum;
import com.joysuch.wwyt.edu.mapper.EduExamRecordsMapper;
import com.joysuch.wwyt.edu.mapper.EduExamUserScopeMapper;
import com.joysuch.wwyt.edu.repository.EduCourseStatisticsDao;
import com.joysuch.wwyt.edu.repository.EduExamDao;
import com.joysuch.wwyt.edu.repository.EduExamRecordDao;
import com.joysuch.wwyt.edu.repository.EduExamUserAnswerDao;
import com.joysuch.wwyt.edu.service.EduExamRecordService;
import com.joysuch.wwyt.edu.service.EduExamService;
import com.joysuch.wwyt.edu.service.EduExamTestPaperService;
import com.joysuch.wwyt.edu.service.EduTestPaperService;
import com.joysuch.wwyt.util.PrintExportUtil;
import com.joysuch.wwyt.util.StringUtil;
import com.joysuch.wwyt.util.ZipUtil;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import java.io.*;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
@Transactional
public class EduExamRecordServiceImpl implements EduExamRecordService {

    @Autowired
    private EduExamRecordDao dao;

    @Autowired
    private EduExamUserAnswerDao examUserAnswerDao;
    @Autowired
    private BizCodeGeneratorFacade bizCodeGeneratorFacade;
    @Autowired
    private EduCourseStatisticsDao eduCourseStatisticsDao;

    @Resource
    private BpDepartDao bpDepartDao;
    @Resource
    private BpJobDao bpJobDao;

    @Resource
    private EduExamRecordsMapper eduExamRecordsMapper;

    @Resource
    private EduExamUserScopeMapper eduExamUserScopeMapper;
    @Resource
    private BaseUserMapper baseUserMapper;
    @Resource
    private BaseUserService baseUserService;
    @Resource
    private EduExamDao eduExamDao;

    @Resource
    private EduExamTestPaperService eduExamTestPaperService;

    @Resource
    private EduTestPaperService eduTestPaperService;

    @Resource
    private EduExamService eduExamService;


    @Autowired
    private PrintExportUtil printExportUtil;

    @Value("${wwyt.base.serverUrl}")
    private String serverUrl;

    @Value("${wwyt.image.upload.dir}")
    private String imageUploadDir;

    @Autowired
    private BaseImageRepositoryService imageService;

    @Override
    public EduExamRecord add(EduExamRecordEditBean entity) {
        EduExamRecord content = new EduExamRecord();
        BeanUtils.copyProperties(entity, content, "id");
        return dao.save(content);
    }

    @Override
    public void update(EduExamRecordEditBean entity) {
        EduExamRecord content = dao.findById(entity.getId()).get();
        BeanUtils.copyProperties(entity, content, "id");
        dao.save(content);
    }

    @Override
    public Page<EduExamRecordListBean> findByPage(Pageable page, SearchEduExamRecord condition) {
        Predicate predicate = prepareListSearchCondition(condition);

        Page<EduExamRecord> data = predicate == null ? dao.findAll(page) : dao.findAll(predicate, page);

        return PageDataUtils.convertPageData(data, new PageDataConvert<EduExamRecordListBean, EduExamRecord>() {

            @Override
            public EduExamRecordListBean convert(EduExamRecord f) {
                EduExamRecordListBean bean = new EduExamRecordListBean();
                BeanUtils.copyProperties(f, bean);
                return bean;
            }

        });
    }

    private Predicate prepareListSearchCondition(SearchEduExamRecord condition) {
        Predicate p = null;
        QEduExamRecord q = QEduExamRecord.eduExamRecord;
        if (condition.getExamId() != null) {
            p = ExpressionUtils.and(p, q.examId.eq(condition.getExamId()));
        }
        if (condition.getUserId() != null) {
            p = ExpressionUtils.and(p, q.userId.eq(condition.getUserId()));
        }
        if (condition.getScore() != null) {
            p = ExpressionUtils.and(p, q.score.eq(condition.getScore()));
        }
        if (condition.getTotalScore() != null) {
            p = ExpressionUtils.and(p, q.totalScore.eq(condition.getTotalScore()));
        }
        if (condition.getPassScore() != null) {
            p = ExpressionUtils.and(p, q.passScore.eq(condition.getPassScore()));
        }
        if (condition.getSummary() != null) {
            p = ExpressionUtils.and(p, q.summary.eq(condition.getSummary()));
        }
        if (condition.getSubmitTime() != null) {
            p = ExpressionUtils.and(p, q.submitTime.eq(condition.getSubmitTime()));
        }
        if (condition.getState() != null) {
            p = ExpressionUtils.and(p, q.state.eq(condition.getState()));
        }
        return p;
    }

    @Override
    public void delete(Long id) throws BusinessRestrictionsException {
        // 校验业务逻辑是否允许删除。如本数据被其他业务关联，删除后导致其他业务不可用。不能删除时将抛出业务异常
        checkBussinessRestrictions(id);
        dao.deleteById(id);
    }

    /**
     * 校验业务逻辑是否允许删除。如本数据被其他业务关联，删除后导致其他业务不可用
     *
     * @param id 要删除的业务ID
     */
    private void checkBussinessRestrictions(Long id) throws BusinessRestrictionsException {

    }

    @Override
    public EduExamRecord findById(Long id) {
        return dao.findById(id).orElse(null);
    }

    @Override
    public ResultBean userInfoExam(Long userId, Pageable pageable) {
        Page<EduExamUserInfoDto> page = dao.userInfoExam(userId, pageable);
        return ResultBean.pageData(page.getContent(), page.getTotalElements());
    }

    @Override
    public EduExamRecordDetailBean getById(Long id) {
        EduExamRecord entity = findById(id);
        if (entity == null) {
            return null;
        }
        EduExamRecordDetailBean bean = new EduExamRecordDetailBean();
        BeanUtils.copyProperties(entity, bean);
        return bean;
    }

    @Override
    public ResultBean queryUserExamRecordAnswerList(Long examRecordId) {
        List<EduExamUserAnswer> list = examUserAnswerDao.findByExamRecordId(examRecordId);
        List<EduExamUserAnswerDetailBean> records = list.stream().map(r -> {
            EduExamUserAnswerDetailBean bean = new EduExamUserAnswerDetailBean();
            bean.setId(r.getId());
            bean.setCorrectFlag(r.getCorrectFlag());
            bean.setCorrect("Y".equals(r.getCorrectFlag()));
            bean.setExamRecordId(examRecordId);
            bean.setAnswer(r.getAnswer());
            bean.setQuestionId(r.getQuestionId());
            bean.setTestPaperQuestionId(r.getTestPaperQuestionId());
            bean.setScore(r.getScore() == null ? "0" : r.getScore() + "");
            return bean;
        }).collect(Collectors.toList());
        return ResultBean.success(records);
    }

    @Override
    public void deleteAll(List<Long> ids) {
        if (ids.size() > 0) {
            dao.deleteAllById(ids);
        }
    }

    @Override
    public void batchDeleteByExamIdAndUserId(Long examId, List<Long> userIdList) {
        //处理学习考试统计的考试次数和通过次数的统计
        updataCourseStatistics(examId, userIdList);
        dao.batchDeleteByExamIdAndUserId(examId, userIdList);
    }

    /**
     * 查询一段时间内的考试记录，某人的、某部门所有员工的、某工作岗位所有员工的、所有的
     *
     * @param eduTrainTimeBean
     * @return
     */
    @Override
    public IPage<EduExamRecord> queryExamRecords(EduTrainTimeBean eduTrainTimeBean, Integer pageNo, Integer pageSize) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<BaseUser> queryPage = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(pageNo, pageSize);

        LambdaQueryWrapper<BaseUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseUser::getDeleteFlag, "0");
        if (eduTrainTimeBean.getDepartId() != null) {
            queryWrapper.eq(BaseUser::getDepartId, eduTrainTimeBean.getDepartId());
        }
        if (eduTrainTimeBean.getJobId() != null) {
            queryWrapper.eq(BaseUser::getJob, eduTrainTimeBean.getJobId());
        }
        if (eduTrainTimeBean.getUserId() != null) {
            queryWrapper.eq(BaseUser::getId, eduTrainTimeBean.getUserId());
        }
        if (!StringUtils.isEmpty(eduTrainTimeBean.getName())) {
            queryWrapper.eq(BaseUser::getRealName, "%" + eduTrainTimeBean.getName() + "%");
        }
        queryWrapper.select(BaseUser::getId, BaseUser::getRealName, BaseUser::getDepartId, BaseUser::getJob);
        IPage<BaseUser> baseUserIPage = baseUserMapper.selectPage(queryPage, queryWrapper);

        List<Long> departIdSet = baseUserIPage.getRecords().stream().map(BaseUser::getDepartId).collect(Collectors.toSet()).stream().collect(Collectors.toList());
        List<Long> jobIdSet = baseUserIPage.getRecords().stream().map(BaseUser::getJob).collect(Collectors.toSet()).stream().collect(Collectors.toList());

        Map<Long, BpDepart> departMap = Maps.newHashMap();
        Map<Long, BpJob> jobMap = Maps.newHashMap();
        if (departIdSet.size() > 0) {
            Map<Long, BpDepart> map = bpDepartDao.findByIdIn(departIdSet).stream().collect(Collectors.toMap(BpDepart::getId, e -> e));
            departMap.putAll(map);
        }
        if (jobIdSet.size() > 0) {
            Map<Long, BpJob> map = bpJobDao.findAllByIdInfo(jobIdSet).stream().collect(Collectors.toMap(BpJob::getId, e -> e));
            jobMap.putAll(map);
        }
        List<EduExamRecord> recordList = Lists.newArrayList();

        baseUserIPage.getRecords().forEach(baseUser -> {
            // 考试数量、参考数量、通过数量（补考用新的成绩）、通过率（通过数量/考试数量）
            EduExamRecord record = new EduExamRecord();
            record.setUserId(baseUser.getId());
            record.setUserName(baseUser.getRealName());
            BpDepart bpDepart = departMap.get(baseUser.getDepartId());
            record.setDepartName(bpDepart == null ? "" : bpDepart.getName());
            BpJob bpJob = jobMap.get(baseUser.getJob());
            record.setJobName(bpJob == null ? "" : bpJob.getName());

            // 查询考试数量
            int examCount = eduExamUserScopeMapper.selectExamCount(baseUser.getId(), baseUser.getJob(), baseUser.getDepartId(), eduTrainTimeBean.getBeginTime(), eduTrainTimeBean.getEndTime());

            // 考试数量
            record.setExamCount(examCount);

            // 参考记录
            List<EduExamRecord> eduExamRecordList = eduExamRecordsMapper.selectExam(baseUser.getId(), eduTrainTimeBean.getBeginTime(), eduTrainTimeBean.getEndTime());

            // 过滤重复的考试ID
            Set<Long> examIdSet = eduExamRecordList.stream().map(EduExamRecord::getExamId).collect(Collectors.toSet());

            // 参考数量
            record.setJoinCountActual(examIdSet.size());

            // 过滤所有考试通过记录并去掉重复的考试ID
            Set<Long> passExamIdSet = eduExamRecordList.stream().filter(e -> e.getScore() != null && Float.valueOf(e.getScore()) >= e.getPassScore()).map(EduExamRecord::getExamId).collect(Collectors.toSet());

            // 通过数量
            record.setPassCount(passExamIdSet.size());

            // 通过率（通过数量/考试数量）
            String passRate = calPassRate(record.getPassCount(), record.getExamCount());
            record.setPassRate(passRate);

            recordList.add(record);
        });
        IPage<EduExamRecord> page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>();
        page.setRecords(recordList);
        page.setTotal(baseUserIPage.getTotal());
        return page;
    }

    @Override
    public void exportPdf(Long examId, HttpServletResponse response, String userIds) throws IllegalArgumentException {
        List<Long> userList = new ArrayList<>();
        if (Strings.isNotBlank(userIds)) {
            String[] split = userIds.split(",");
            for (String s : split) {
                userList.add(Long.parseLong(s));
            }
        }
        EduExam eduExam = eduExamDao.findById(examId).get();
        if (eduExam == null) {
            throw new IllegalArgumentException("该考试未查询到");
        }
        EduTestPaper testPaper = eduTestPaperService.findByExamId(examId);
        //该考试的记录
        List<EduExamRecord> eduExamRecords = eduExamRecordsMapper.selectByExamId(examId, userList);
        if (CollectionUtils.isEmpty(eduExamRecords)) {
            throw new IllegalArgumentException("该考试暂时无人提交");
        }
        Map recordMap = new HashMap();
        for (EduExamRecord record : eduExamRecords) {
            if (recordMap.get(record.getUserId()) == null) {
                recordMap.put(record.getUserId(), record);
            }
        }
        eduExamRecords = new ArrayList<>(recordMap.values());
        List<Long> ids = userList;
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(userList)) {
            ids = eduExamRecords.stream().map(EduExamRecord::getUserId).collect(Collectors.toList());
        }
        List<BaseUser> users = baseUserMapper.findByUserIds(ids);
        Map<Long, BaseUser> userMap = new HashMap<>();
        for (BaseUser user : users) {
            userMap.put(user.getId(), user);
        }
        List<Long> departIdSet = users.stream().map(BaseUser::getDepartId).collect(Collectors.toSet()).stream().collect(Collectors.toList());
        List<Long> jobIdSet = users.stream().map(BaseUser::getJob).collect(Collectors.toSet()).stream().collect(Collectors.toList());
        Map<Long, BpDepart> departMap = Maps.newHashMap();
        Map<Long, BpJob> jobMap = Maps.newHashMap();
        if (departIdSet.size() > 0) {
            Map<Long, BpDepart> map = bpDepartDao.findByIdIn(departIdSet).stream().collect(Collectors.toMap(BpDepart::getId, e -> e));
            departMap.putAll(map);
        }
        if (jobIdSet.size() > 0) {
            Map<Long, BpJob> map = bpJobDao.findAllByIdInfo(jobIdSet).stream().collect(Collectors.toMap(BpJob::getId, e -> e));
            jobMap.putAll(map);
        }
        List<File> files = new ArrayList<>();
        for (EduExamRecord record : eduExamRecords) {
            EduPaperPdfBean bean = new EduPaperPdfBean();
            //查询用户答案
            List<EduExamUserAnswer> list = examUserAnswerDao.findByExamRecordId(record.getId());

            Map<Long, EduExamUserAnswer> map = new HashMap<>();
            for (EduExamUserAnswer eduExamUserAnswer : list) {
                map.put(eduExamUserAnswer.getQuestionId(), eduExamUserAnswer);
            }
            List<EduTestPaperQuestionDetailBean> beans = eduExamService.queryQuestionListByExamId(examId, 1, record.getUserId(), null);
            Map<Long, EduTestPaperQuestionDetailBean> beanMap = beans.stream().collect(Collectors.toMap(EduTestPaperQuestionDetailBean::getId, Function.identity()));
            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(list)) {
                List<EduTestPaperQuestionDetailBean> newList = new ArrayList<>();
                for (EduExamUserAnswer answer : list) {
                    newList.add(beanMap.get(answer.getTestPaperQuestionId()));
                }
                beans = newList;
            }
            bean.setPaperName(testPaper.getName());
            bean.setExamName(eduExam.getName());
            if (StringUtils.isNotBlank(bean.getExamName()) && bean.getExamName().contains("<")) {
                // 文件名包含特殊字符时, 需要转义, 不然html文件中识别会报错
                String examName = bean.getExamName().replaceAll("<", "&lt;");
                bean.setExamName(examName);
            }
            bean.setRightCount(record.getRightCount());
            bean.setWrongCount(record.getWrongCount());
            if (userMap.get(record.getUserId()) != null) {
                bean.setName(userMap.get(record.getUserId()).getRealName());
            }

            bean.setIsFirst(record.getSubmitTimes() > 1 ? "是" : "否");
            bean.setScore(record.getScore());
            if (jobMap.get(userMap.get(record.getUserId()).getJob()) != null) {
                bean.setJobName(jobMap.get(userMap.get(record.getUserId()).getJob()).getName());
            }
            if (departMap.get(userMap.get(record.getUserId()).getDepartId()) != null) {
                bean.setDepartName(departMap.get(userMap.get(record.getUserId()).getDepartId()).getName());
            }
            String autograph = "";
            if (StringUtils.isNotBlank(record.getRotatePath())) {
                autograph = record.getRotatePath();
            } else {
                if (StringUtils.isNotBlank(record.getAutograph())) {
                    int i = record.getAutograph().indexOf("=");
                    String id = record.getAutograph().substring(i + 1, record.getAutograph().length());
                    BaseImageRepository image = imageService.findById(Long.parseLong(id));
                    autograph = imageUploadDir + File.separator + image.getOriginPath();
                }
            }
            bean.setAutograph(autograph);
            bean.setSubmitTime(DateUtil.format(record.getSubmitTime(), "yyyy-MM-dd HH:mm"));
            Double subjectiveScore = 0d;
            Double objectiveScore = 0d;
            List<EduPaperPdfSubjectBean> subjectBeanList = new ArrayList<>();
            for (EduTestPaperQuestionDetailBean paperQuestionDetailBean : beans) {
                EduPaperPdfSubjectBean subjectBean = new EduPaperPdfSubjectBean();
                String name = paperQuestionDetailBean.getName();
                if (!StringUtil.isEmpty(name)) {
                    if (name.contains(CharacterEntityEnum.DA_YU.getShowStr())) {
                        name = name.replaceAll(CharacterEntityEnum.DA_YU.getShowStr(), CharacterEntityEnum.DA_YU.getEscapeSequence());
                    }
                    if (name.contains(CharacterEntityEnum.XIAO_YU.getShowStr())) {
                        name = name.replaceAll(CharacterEntityEnum.XIAO_YU.getShowStr(), CharacterEntityEnum.XIAO_YU.getEscapeSequence());
                    }
                }
                subjectBean.setName(name);
                subjectBean.setType(paperQuestionDetailBean.getTypeName());
                List<String> optionList = paperQuestionDetailBean.getChoices();
                String rightKey = paperQuestionDetailBean.getAnswer();
                // 判断题,修改描述
                if (DistributionQuestionTypes.JUDGE.getCode().equals(paperQuestionDetailBean.getType())) {
                    // 修改正确答案描述
                    rightKey = ("是".equals(rightKey) || "A".equals(rightKey)) ? "正确" : "错误";
                    // 修改选项描述
                    List<String> options = Lists.newArrayList();
                    options.add("A、正确");
                    options.add("B、错误");
                    optionList = options;
                }
                if (!StringUtil.isEmpty(rightKey)) {
                    if (rightKey.contains(CharacterEntityEnum.DA_YU.getShowStr())) {
                        rightKey = rightKey.replaceAll(CharacterEntityEnum.DA_YU.getShowStr(), CharacterEntityEnum.DA_YU.getEscapeSequence());
                    }
                    if (rightKey.contains(CharacterEntityEnum.XIAO_YU.getShowStr())) {
                        rightKey = rightKey.replaceAll(CharacterEntityEnum.XIAO_YU.getShowStr(), CharacterEntityEnum.XIAO_YU.getEscapeSequence());
                    }
                }
                List<String> newChoices = Lists.newArrayList();
                if (CollectionUtils.isNotEmpty(optionList)) {
                    optionList.forEach(item -> {
                        if (!StringUtil.isEmpty(item)) {
                            if (item.contains(CharacterEntityEnum.DA_YU.getShowStr())) {
                                item = item.replaceAll(CharacterEntityEnum.DA_YU.getShowStr(), CharacterEntityEnum.DA_YU.getEscapeSequence());
                            }
                            if (item.contains(CharacterEntityEnum.XIAO_YU.getShowStr())) {
                                item = item.replaceAll(CharacterEntityEnum.XIAO_YU.getShowStr(), CharacterEntityEnum.XIAO_YU.getEscapeSequence());
                            }
                            newChoices.add(item);
                        }
                    });
                }
                subjectBean.setRightKey(rightKey);
                subjectBean.setOptionList(newChoices);
                String result = "错";
                if (!paperQuestionDetailBean.getType().equals("Z")) {
                    if (map.get(paperQuestionDetailBean.getQuestionId()) != null && map.get(paperQuestionDetailBean.getQuestionId()).getCorrectFlag().equals("Y")) {
                        result = "对";
                        objectiveScore = objectiveScore + map.get(paperQuestionDetailBean.getQuestionId()).getScore();
                    }
                } else {
                    if (map.get(paperQuestionDetailBean.getQuestionId()) != null && map.get(paperQuestionDetailBean.getQuestionId()).getScore() != null) {
                        result = map.get(paperQuestionDetailBean.getQuestionId()).getScore() + "";
                        subjectiveScore = subjectiveScore + map.get(paperQuestionDetailBean.getQuestionId()).getScore();
                    } else {
                        result = "0";
                    }
                }

                subjectBean.setResult(result);
                String userAnswer = "";
                if (map.get(paperQuestionDetailBean.getQuestionId()) != null) {
                    EduExamUserAnswer eduExamUserAnswer = map.get(paperQuestionDetailBean.getQuestionId());
                    if (map.get(paperQuestionDetailBean.getQuestionId()).getAnswer() != null && !eduExamUserAnswer.getAnswer().equals("")) {
                        userAnswer = map.get(paperQuestionDetailBean.getQuestionId()).getAnswer();
                        // 判断题, 修改考员答案描述。
                        if (DistributionQuestionTypes.JUDGE.getCode().equals(paperQuestionDetailBean.getType())) {
                            userAnswer = ("是".equals(userAnswer) || "A".equals(userAnswer)) ? "正确" : "错误";
                        }
                        if (userAnswer.contains(CharacterEntityEnum.DA_YU.getShowStr())) {
                            userAnswer = userAnswer.replaceAll(CharacterEntityEnum.DA_YU.getShowStr(), CharacterEntityEnum.DA_YU.getEscapeSequence());
                        }
                        if (userAnswer.contains(CharacterEntityEnum.XIAO_YU.getShowStr())) {
                            userAnswer = userAnswer.replaceAll(CharacterEntityEnum.XIAO_YU.getShowStr(), CharacterEntityEnum.XIAO_YU.getEscapeSequence());
                        }
                    }
                }

                subjectBean.setUserAnswer(userAnswer);
                subjectBeanList.add(subjectBean);
            }
            bean.setShowAutograph(eduExam.getShowAutograph() == 1 ? true : false);
            bean.setList(subjectBeanList);
            bean.setSubjectiveScore(subjectiveScore);
            bean.setObjectiveScore(objectiveScore);
            File pdfFile = null;
            try {
                String regex = "[/\\\\:*?|<>\"]";
                pdfFile = printExportUtil.generateNewPDF(beanToMap(bean), "paperTemplate", eduExam.getName().replaceAll(regex, "") + bean.getName());
            } catch (Exception e) {
                log.error("转换pdf文件失败");
                e.printStackTrace();
            }
            files.add(pdfFile);
        }

        ServletOutputStream outputStream = null;
        try {
            String regex = "[/\\\\:*?|<>\"]";
            String fileName = eduExam.getName().replaceAll(regex, "") + ".zip";
            fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ";filename*=utf-8''" + fileName);
            outputStream = response.getOutputStream();
        } catch (IOException e) {
            log.error("压缩文件失败");
            e.printStackTrace();
        }
        ZipUtil.toZip(files, outputStream, true);

    }


    /**
     * 文件转base64字符串
     *
     * @param path
     * @return
     */
    public static String fileToBase64(String path) {
        String base64 = null;
        InputStream in = null;
        try {
            in = new FileInputStream(new File(path));
            byte[] bytes = ByteStreams.toByteArray(in);
            base64 = Base64.getEncoder().encodeToString(bytes);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return base64;
    }


    public static Map beanToMap(Object object) throws IllegalAccessException {
        Map<String, Object> map = new HashMap<String, Object>();
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            map.put(field.getName(), field.get(object));
        }
        return map;
    }

    private String calPassRate(Integer passCount, Integer examCount) {
        if (examCount == 0 || passCount == 0) {
            return "0%";
        }
        BigDecimal bg = new BigDecimal(passCount);
        bg = bg.divide(new BigDecimal(examCount), 4, BigDecimal.ROUND_HALF_UP);
        bg = bg.multiply(new BigDecimal(100));
        bg = bg.setScale(0, BigDecimal.ROUND_HALF_UP);
        return bg.doubleValue() + "%";
    }

    /**
     *根据用户id，获取该用户的考试记录信息：人员姓名、部门名称、岗位名称、应参与考试数量、实际参与数量、通过数量、通过率
     * @param userId
     * @param beginTime
     * @param endTime
     * @return
     *//*
    private EduExamRecord getRecords(Long userId, Date beginTime, Date endTime){
        //userId获取该用户多个考试记录信息
        List<EduExamRecord> eduExamRecords = eduExamRecordsMapper.queryExamRecordsByuserId(userId,beginTime,endTime);
        if (eduExamRecords.size() == 0) {
            throw new IllegalArgumentException("无记录");
        }
        EduExamRecord eduExamRecordR = eduExamRecords.get(0);//获取该用户基本信息
        int joinCountActual = eduExamRecords.size();//获取该用户实际参与的考试数量
        eduExamRecordR.setJoinCountActual(joinCountActual);//参考数量，实际参与的考试数量
        //获取该用户应该参与的考试数量
        QueryWrapper<EduExamUserScope> wrapper = new QueryWrapper<>();
        wrapper.eq("OBJ_ID",eduExamRecordR.getUserId());
        Integer examCount = eduExamUserScopeMapper.selectCount(wrapper);
        //遍历该用户考试记录，获取通过次数
        Integer passCount = 0;
        for (EduExamRecord eduExamRecord : eduExamRecords) {
            if (eduExamRecord.getScore() >= eduExamRecord.getPassScore())
                //得分大于等于及格分，通过数量加1
                passCount++;
        }

        eduExamRecordR.setExamCount(examCount);//考试数量，应该参与的考试数量
        eduExamRecordR.setPassCount(passCount);//通过数量
        //设置通过率
        NumberFormat numberFormat = NumberFormat.getInstance();
        numberFormat.setMaximumFractionDigits(2);
        //通过的数量 / 应该参与的数量
        String format = numberFormat.format((double) passCount / (double) examCount * 100)+"%";
        eduExamRecordR.setPassRate(format);//通过率
        return eduExamRecordR;
    }*/

    /**
     * @param examId     考试的id
     * @param userIdList 删除的人员的ids
     */
    public void updataCourseStatistics(Long examId, List<Long> userIdList) {

        List<EduExamRecord> list = dao.findByExamIdAndUserIds(examId, userIdList);
        List<Long> userIds = new ArrayList<>();
        List<BaseUser> userList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            for (EduExamRecord record : list) {
                userIds.add(record.getUserId());
            }
        }
        if (CollectionUtils.isNotEmpty(userIds)) {
            userList = baseUserService.getAllByIdsAndShowState(userIds);
        }
        if (CollectionUtils.isNotEmpty(userList)) {
            StringBuffer str = new StringBuffer();
            for (BaseUser user : userList) {
                str.append(user.getRealName() + ",");
            }
            throw new IllegalArgumentException("考试人员:" + str.toString() + "不可删除包含未阅卷的考试记录");
        }
        EduExam one = eduExamDao.getOne(examId);
        if (one.getFormType() != 0){
        for (Long userId : userIdList) {
            EduExamRecord record = dao.selectByUserIdAndExamIdLatest(userId, examId);
//            if (record.getIsCheck() == 1) {
//                BpUserListBean bean = baseUserService.findById(userId);
//                throw new IllegalArgumentException("考试人员" + bean.getRealName() + ",不可删除包含未阅卷的考试记录");
//            }
            EduCourseStatistics eduCourseStatistics = eduCourseStatisticsDao.selectByUserId(userId);
            //如果考试状态是通过则此人的考试通过次数减一，反之不变，考试次数必定减一
            Integer examCount = eduCourseStatistics.getExamCount();
            Integer examPassCount = eduCourseStatistics.getExamPassCount();
            eduCourseStatistics.setExamCount(examCount - 1);
            eduCourseStatistics.setExamPassCount(record.getState() == 1 ? examPassCount - 1 : examPassCount);
            eduCourseStatisticsDao.save(eduCourseStatistics);
        }
           }
    }

}
